/********************************Copyright (c)**********************************\
**
**                   (c) Copyright 2025, Main, China, QD.
**                           All Rights Reserved
**
**                                 By(wo4fisher)
**                           http://www.wo4fisher.com
**
**----------------------------------文件信息------------------------------------
** 文件名称: ringBuf.c
** 创建人员: wht
** 创建日期: 2025-08-15
** 文档描述:
**
**----------------------------------版本信息------------------------------------
** 版本代号: V0.1
** 版本说明: 初始版本
**
**------------------------------------------------------------------------------
\********************************End of Head************************************/
#include "ringBuf.h"
#include <string.h>

// 全局缓冲区
volatile ring_buffer_t uart_buffer = {0};

// 初始化循环缓冲区
void ring_buffer_init(ring_buffer_t *rb)
{
    rb->head = 0;
    rb->tail = 0;
    rb->count = 0;
}

// 检查缓冲区是否为空
uint8_t ring_buffer_is_empty(ring_buffer_t *rb)
{
    return (rb->count == 0);
}

// 检查缓冲区是否已满
uint8_t ring_buffer_is_full(ring_buffer_t *rb)
{
    return (rb->count == RING_BUFFER_SIZE);
}

// 向缓冲区写入数据（串口中断中调用）
uint8_t ring_buffer_write(ring_buffer_t *rb, uint8_t data)
{
    if (ring_buffer_is_full(rb))
    {
        return 0; // 缓冲区已满
    }

    rb->buffer[rb->head] = data;
    rb->head = (rb->head + 1) % RING_BUFFER_SIZE;
    rb->count++;

    return 1; // 写入成功
}

// 从缓冲区读取数据
uint8_t ring_buffer_read(ring_buffer_t *rb, uint8_t *data)
{
    if (ring_buffer_is_empty(rb))
    {
        return 0; // 缓冲区为空
    }

    *data = rb->buffer[rb->tail];
    rb->tail = (rb->tail + 1) % RING_BUFFER_SIZE;
    rb->count--;

    return 1; // 读取成功
}

// 批量读取数据
uint16_t ring_buffer_read_multi(ring_buffer_t *rb, uint8_t *data, uint16_t length)
{
    uint16_t i;

    for (i = 0; i < length; i++)
    {
        if (!ring_buffer_read(rb, &data[i]))
        {
            break;
        }
    }

    return i; // 返回实际读取的字节数
}

// 查看缓冲区中指定位置的数据（不移动读指针）
uint8_t ring_buffer_peek(ring_buffer_t *rb, uint16_t index, uint8_t *data)
{
    if (index >= rb->count)
    {
        return 0; // 索引超出范围
    }

    uint16_t actual_index = (rb->tail + index) % RING_BUFFER_SIZE;
    *data = rb->buffer[actual_index];
    return 1;
}

// 获取缓冲区中可用数据量
uint16_t ring_buffer_available(ring_buffer_t *rb)
{
    return rb->count;
}

// 协议解析函数
protocol_type_t parse_protocol_type(uint8_t header)
{
    switch (header)
    {
    case PROTOCOL1_HEADER:
        return PROTOCOL_TYPE1;

    case PROTOCOL2_HEADER:
        return PROTOCOL_TYPE2;

    case PROTOCOL3_HEADER:
        return PROTOCOL_TYPE3;

    default:
        return PROTOCOL_UNKNOWN;
    }
}

// 解析特定协议
protocol_type_t parse_protocol_data(ring_buffer_t *rb, protocol_result_t *result)
{
    if (ring_buffer_available(rb) < 3)   // 至少需要帧头+长度字段
    {
        return PROTOCOL_UNKNOWN;
    }

    uint8_t header;
    uint8_t length;

    // 查看帧头
    if (!ring_buffer_peek(rb, 0, &header))
    {
        return PROTOCOL_UNKNOWN;
    }

    protocol_type_t protocol_type = parse_protocol_type(header);

    if (protocol_type == PROTOCOL_UNKNOWN)
    {
        // 跳过无效字节
        uint8_t dummy;
        ring_buffer_read(rb, &dummy);
        return PROTOCOL_UNKNOWN;
    }

    // 查看数据长度
    if (!ring_buffer_peek(rb, 1, &length))
    {
        return PROTOCOL_UNKNOWN;
    }

    // 检查缓冲区中是否有完整帧
    if (ring_buffer_available(rb) < (2 + length))   // 帧头+长度+数据
    {
        return PROTOCOL_UNKNOWN; // 数据不完整
    }

    // 跳过帧头和长度字段，指向数据区
    uint16_t current_tail = rb->tail;
    rb->tail = (rb->tail + 2) % RING_BUFFER_SIZE;
    rb->count -= 2;

    // 设置返回结果
    result->protocol_type = protocol_type;
    result->data_ptr = &rb->buffer[rb->tail]; // 注意：这里是指针，可能需要根据实际情况调整
    result->data_length = length;

    // 恢复读指针位置并跳过已解析的数据
    rb->tail = (rb->tail + length) % RING_BUFFER_SIZE;
    rb->count -= length;

    return protocol_type;
}

// 更安全的协议解析（复制数据而不是返回指针）
protocol_type_t parse_protocol_safe(ring_buffer_t *rb, uint8_t *data_buffer,
                                    uint16_t buffer_size, protocol_result_t *result)
{
    if (ring_buffer_available(rb) < 3)
    {
        return PROTOCOL_UNKNOWN;
    }

    uint8_t header, length;

    // 临时读取帧头和长度进行检查
    uint16_t temp_tail = rb->tail;
    uint16_t temp_count = rb->count;

    ring_buffer_peek(rb, 0, &header);
    protocol_type_t protocol_type = parse_protocol_type(header);

    //不是帧头，直接读掉脏数据，然后返回，等下一次进来再读下一个字节
    if (protocol_type == PROTOCOL_UNKNOWN)
    {
        uint8_t dummy;
        ring_buffer_read(rb, &dummy);
        return PROTOCOL_UNKNOWN;
    }

    // 数据长度
    ring_buffer_peek(rb, 1, &length);

    //看可用数据是否够一帧完整数据  帧头 长度 数据*4 帧尾*3(FF FF FF);长度包括数据和帧尾，所以是2+length
    if (ring_buffer_available(rb) < (2 + length))
    {
        return PROTOCOL_UNKNOWN;
    }

    //这里应该是够，一帧数据不会超12
    if (length > buffer_size)
    {
        return PROTOCOL_UNKNOWN; // 缓冲区不够
    }

    // 读取完整帧 正常读；  上面的是用来判断，临时读，头、尾指针不动
    uint8_t temp_byte;
    ring_buffer_read(rb, &temp_byte); // 帧头
    ring_buffer_read(rb, &temp_byte); // 长度

    // 读取数据区
    ring_buffer_read_multi(rb, data_buffer, length);

    result->protocol_type = protocol_type;
    result->data_ptr = data_buffer;
    result->data_length = length;

    return protocol_type;
}

volatile uint8_t hr_rx_data = 0;

// 初始化函数
void communication_init(void)
{
    ring_buffer_init(&uart_buffer);
    // 初始化串口等其他硬件
    MX_USART3_UART_Init();
//    MX_UART3_TX_DMA_Init();

//    HAL_UART_Receive_IT ( &huart3, ( uint8_t * ) &hr_rx_data, 1 );
}

// HMI 触摸屏发送数据,单片机接收到
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{

    ring_buffer_write(&uart_buffer, hr_rx_data);
//    HAL_UART_Receive_IT( &huart3, ( uint8_t * ) &hr_rx_data, 1 );

}

extern volatile uint8_t uart3_txc_flag; // 向hmi传输完成标志 发送中等于1，发送完之后等于0

// 触摸屏发送完成回调函数
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle)
{
    uart3_txc_flag = 0;

}
/********************************End of File************************************/